package cate.common.util;

import cate.common.annotation.SplitParse;
import cate.common.table.item.ItemPackRow;
import cate.common.util.random.RWList;
import cp.solution.util.str.Str;
import easy.java.practice.errorcode.EcException;
import easy.java.runtime.reflect.FieldReflect;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

public class SplitParser {

    public static <T> List<T> parse(Class<T> clz, String content) {
        if (content == null) {
            return null;
        }
        List<T> result = new ArrayList<>();
        if (StringUtils.isEmpty(content)) {
            return result;
        }
        String arraySeperator = "#";
        String fieldSepertaor = ":";
        SplitParse spClz = clz.getAnnotation(SplitParse.class);
        if (spClz != null) {
            arraySeperator = spClz.arraySeperator();
            fieldSepertaor = spClz.fieldSeperator();
        }
        List<Field> fields = FieldReflect.findUserDefinedFields(clz);
        content = StringUtils.trim(content);
        String[] itemStrArr = content.split(arraySeperator);
        for (String itemStr : itemStrArr) {
            if (StringUtils.isBlank(itemStr)) {
                continue;
            }
            String[] fieldStrArr = itemStr.split(fieldSepertaor);
            T item = null;
            try {
                item = clz.getConstructor().newInstance();
                for (Field f : fields) {
                    SplitParse sp = f.getAnnotation(SplitParse.class);
                    if (sp == null) {
                        continue;
                    }
                    String strVal = sp.defaultValue();
                    if (fieldStrArr.length > sp.order()) {
                        String tmp = fieldStrArr[sp.order()];
                        if (!StringUtils.isBlank(tmp)) {
                            strVal = tmp;
                        }
                    }
                    Object value = null;
                    if (String.class == f.getType()) {
                        value = strVal;
                    } else if (int.class == f.getType()) {
                        value = Str.toInteger(strVal, 0);
                    } else if (Integer.class == f.getType()) {
                        value = Str.toInteger(strVal, null);
                    } else if (long.class == f.getType()) {
                        value = Str.toLong(strVal, 0L);
                    } else if (Long.class == f.getType()) {
                        value = Str.toLong(strVal, null);
                    } else if (short.class == f.getType()) {
                        value = Str.toShort(strVal, (short) 0);
                    } else if (Short.class == f.getType()) {
                        value = Str.toShort(strVal, null);
                    } else if (double.class == f.getType()) {
                        value = Str.toDouble(strVal, 0d);
                    } else if (Double.class == f.getType()) {
                        value = Str.toDouble(strVal, null);
                    } else if (float.class == f.getType()) {
                        value = Str.toFloat(strVal, 0f);
                    } else if (Float.class == f.getType()) {
                        value = Str.toFloat(strVal, null);
                    } else if (boolean.class == f.getType()) {
                        value = Str.toBoolean(strVal, false);
                    } else if (Boolean.class == f.getType()) {
                        value = Str.toBoolean(strVal, null);
                    } else if (byte.class == f.getType()) {
                        value = Str.toByte(strVal, (byte) 0);
                    } else if (Byte.class == f.getType()) {
                        value = Str.toByte(strVal, null);
                    }
                    f.setAccessible(true);
                    f.set(item, value);
                }
            } catch (Exception e) {
                throw new EcException(content + "分割解析异常" + e);
            }
            result.add(item);
        }
        return result;
    }

    public static <T> T parseOne(Class<T> clz, String content) {
        List<T> result = parse(clz, content);
        if (XT.isBlank(result)) {
            return null;
        }
        return result.get(0);
    }

    public static RWList<ItemPackRow.UncertainItem> unCertainParse(String content) {
        RWList<ItemPackRow.UncertainItem> result = new RWList<>();
        if (StringUtils.isBlank(content)) {
            return result;
        }
        String arraySeperator = "#";
        String fieldSepertaor = ":";
        String uncertainSepertaor = "&";
        content = StringUtils.trim(content);
        String[] itemStrArr = content.split(arraySeperator);
        for (String itemStr : itemStrArr) {
            if (StringUtils.isBlank(itemStr)) {
                continue;
            }
            String itemConfig = itemStr.replaceAll(uncertainSepertaor, arraySeperator);
            ItemPackRow.UncertainItem item = new ItemPackRow.UncertainItem();
            item.res = itemConfig.substring(0, itemConfig.lastIndexOf(fieldSepertaor));
            item.weight = Double.parseDouble(itemConfig.substring(itemStr.lastIndexOf(fieldSepertaor) + 1));
            result.add(item);
        }
        result.setup();
        return result;
    }
}
